# -*- coding:utf-8 -*-
"""日志"""

import os
import sys
import traceback
import logging
from logging.handlers import RotatingFileHandler

from common.pathmgr import PathConfig


class LoggerManager(object):
    """
        合建日志记录器，每条日志根据等级至少显示在控件台，如果级别高于或等于INFO，则写入文件
        当文件大小达到*M的时候，重新建一个新的文件，命名方式是在原文件名的后面加 .*，*的取
        值为 (1,2,3,4,5,6,...)
    """
    LOG_FILE_MAXCOUNT = 9  # 每种日志记录器最多使用多少个文件来记录日志
    LOG_FILE_MAXSIZE = 20  # 每个日志文件最大尺寸，以M为单位

    def __init__(self, logfile_root=None):
        self.__logfileroot = logfile_root
        if not self.__logfileroot:
            self.__logfileroot = PathConfig.LOG_ROOT
        self.__Loggers = {}

    def getLogger(self, name=None, toPrint=True):
        """
            取得一个日志记录器，如果logger已经存在，则返回; 
            如果不存在，则初始化一个logger返回 
        """
        if not name:
            name = 'info'
        if name in self.__Loggers:
            return self.__Loggers[name]

        return self.__initLogger(name, toPrint)

    def __initLogger(self, name, toPrint=True):
        if name in self.__Loggers:
            return self.__Loggers[name]
        else:
            logger = logging.getLogger(name)
            if not len(logger.handlers):  # 表示这个logger还没有设置
                code_path = traceback.extract_stack()[0][0]
                if code_path and code_path.lower().startswith(PathConfig.PROJECT_FOLDER.lower()):
                    code_path = code_path[len(PathConfig.PROJECT_FOLDER):]
                    if code_path[0] in ("\\", "/"):
                        code_path = code_path[1:]
                    filename = code_path.replace("\\", ".").replace("/", ".")
                else:
                    filename = os.path.basename(code_path)

                fpath = os.path.join(self.__logfileroot, os.path.splitext(filename)[0])
                if not os.path.exists(fpath):
                    try:
                        os.makedirs(fpath)
                    except:
                        pass

                fname = os.path.join(fpath, name + ".log")

                # 将大于或等于INFO级别的信息输出到文件，文件大小超出LOG_FILE_MAXSIZE(M)时，自动新建文件
                fmt = logging.Formatter("%(asctime)s [%(levelname)s] [%(process)s] %(message)s", "")
                # 每个日志文件不超过 LOG_FILE_MAXSIZE(M)
                fh = RotatingFileHandler(fname, "a", 1024 * 1024 * self.LOG_FILE_MAXSIZE, self.LOG_FILE_MAXCOUNT)
                fh.setFormatter(fmt)
                fh.setLevel(logging.INFO)
                logger.addHandler(fh)

                if toPrint:
                    # 将大于或等于DEBUG级别的信息输出到控件台
                    cmt = logging.Formatter("%(message)s", "")
                    ch = logging.StreamHandler(sys.stdout)
                    ch.setFormatter(cmt)
                    ch.setLevel(logging.DEBUG)
                    logger.addHandler(ch)

                logger.propagate = False  # 设置不可被继承()
                logger.setLevel(logging.DEBUG)

                self.__Loggers[name] = logger

        return logger


if __name__ == "__main__":
    logfile_root = "c:/custom_logger_test"
    l = LoggerManager().getLogger("log1")
    l2 = LoggerManager().getLogger("log2", False)

    for i in range(1):
        l.debug("debug")
        l.info("info")
        l.warning("warning")

        l2.debug("debug")
        l2.info("info")
        l2.warning("warning")
        l2.error('error')
